package jpm.common;

import static jpm.common.AssertUtils.ensure;
import static jpm.common.AssertUtils.ensureEqual;
import static jpm.common.AssertUtils.ensureNotNull;

import java.util.ArrayList;
import java.util.List;

import jpm.common.JPMException.ErrorCode;

public class ListOfListBuilder {
	private List<List<Integer>> listOfList = new ArrayList<>();

	public static ListOfListBuilder getBuilder() {
		return new ListOfListBuilder();
	}

	public ListOfListBuilder append(int... row) {
		ensureNotNull(listOfList, "listOfList is null");

		// convert array to list
		List<Integer> list = new ArrayList<>();
		for (int element : row) {
			list.add(element);
		}

		listOfList.add(list);

		return this;
	}

	public ListOfListBuilder append(List<Integer> list) {
		ensureNotNull(listOfList, "listOfList is null");
		ensureNotNull(list, "list is null");

		listOfList.add(list);

		return this;
	}

	public ListOfListBuilder append(List<String> strings, String regex) {
		ensureNotNull(strings, "s is null");
		ensureNotNull(regex, "delimiter is null");
		ensure(!regex.isEmpty(), "delimiter is empty");

		if (strings.isEmpty())
			return this;

		List<List<Integer>> rows = new ArrayList<>();

		for (int listIndex = 0; listIndex < strings.size(); listIndex++) {
			String string = strings.get(listIndex);
			
			if (string.isEmpty())
				continue;

			String split[] = string.split(regex);

			for (int arrayIndex = 0; arrayIndex < split.length; arrayIndex++) {
				if (!Utils.canParseAsInt(split[arrayIndex]))
					throw new JPMException().errorType(
							ErrorCode.ERROR_INVALID_INPUT).message(
							"Error in line [" + (listIndex + 1)
									+ "] - cannot parse [" + split[arrayIndex]
									+ "] as an integer. (Note: space should be used as delimiter in input file)");
			}

			List<Integer> row = new ArrayList<>(split.length);
			for (int arrayIndex = 0; arrayIndex < split.length; arrayIndex++) {
				row.add(Utils.safeParseAsInt(split[arrayIndex]));
			}

			ensureEqual(split.length, row.size(),
					"something wrong populating row");

			rows.add(row);
		}

		listOfList.addAll(rows);

		return this;
	}

	public List<List<Integer>> get() {
		return listOfList;
	}
}
